﻿using Esosi.Entity;
using Esosi.Register.Hospital.Models;
using Esosi.Repository;
using Esosi.Repository.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Esosi.Register.Hospital.HospitalPolicy
{
    /*总计政策
   * 1.先计算分类支付政策
   * 2.总计定额无法直接得出分类的计算，需要自己拼凑
         先进行分类汇总，然后按照FIFO的形式进行金额分配
   * 3.返回支付方式费用实体
   */

    /// <summary>
    /// 合计支付政策（总计定额）
    /// </summary>
    public class SumPolicyStrategy : PolicyStrategyBase
    {
        public SumPolicyStrategy(GmChargePolicy gmChargePolicy) : base(gmChargePolicy)
        {
        }

        public override PaySum ApplyPolicy(RegisterHospitalTpi tpi)
        {
            //根据费用汇总分类金额
            var sortSums = tpi.FeeItems.
                GroupBy(p => new { p.IApplyStatus, p.IFeeTypeCode, p.PolicyFeeTypeCode, p.ReckoningTypeCode }).
                Select(g => new SortSum
                {
                    IApplyStatus = g.Key.IApplyStatus,
                    IFeeTypeCode = g.Key.IFeeTypeCode,
                    PolicyFeeTypeCode = g.Key.PolicyFeeTypeCode,
                    ReckoningTypeCode = g.Key.ReckoningTypeCode,
                    FeeAmount = g.Sum(p => p.Summary)
                }
            ).ToList();

            //var paySum = _gmChargePolicy.//GroupBy(a => a.InvoicePayModeCode).
            // Select(p => new PaySum
            // {
            //     InvoicePayMode = (InvoicePayMode)p.InvoicePayModeCode,
            //     FeeSum = CalcSum(p.Percent, p.Ration, tpi.FeeItems.Sum(x => x.Summary)),
            //     SortSums = sortSums
            // });

            var paySum = new PaySum
            {
                InvoicePayMode = (InvoicePayMode)_gmChargePolicy.InvoicePayModeCode,
                FeeSum = CalcSum(_gmChargePolicy.Percent, _gmChargePolicy.Ration, tpi.FeeItems.Sum(x => x.Summary)),
                SortSums = sortSums
            };

            //分摊费用到明细
            var payFeeSum = paySum.FeeSum;
            foreach (var sortSum in paySum.SortSums)
            {
                sortSum.FeeAmount = Math.Min(sortSum.FeeAmount, payFeeSum);
                payFeeSum -= sortSum.FeeAmount;
            }

            return paySum;
        }

        private decimal CalcSum(decimal percent, decimal ration, decimal feeSum)
        {
            var rationSum = feeSum * percent + ration;
            rationSum = Math.Round(rationSum, 2, MidpointRounding.AwayFromZero);
            return Math.Min(feeSum, rationSum > 0 ? rationSum : 0);
        }
    }
}